const dayjs = require('dayjs');
const { Controller } = require('varal');
const { rand } = require('../../helpers/function');

const WxPay = require('wechatpay-node-v3');
const fs = require('fs');
const path = require('path');
const Weapp = require('../../libs/weapp');

const { Order } = require('../../models');
const sequelize = require('sequelize');

class OrderController extends Controller {
	async index() {
		const { page = 1, page_size = 20, is_cart, is_draft, id } = this.app.fields;

		const serv = this.app.service('OrderService');
		return serv.get({
			is_cart,
			is_draft,
			user_id: this.app.auth?.id,
			id
		}, page, page_size).then(({ data, total }) => {
			this.app.json({
				err_code: 0,
				data: {
					data,
					total
				}
			});
		})
	}

	async info() {
		const { out_trade_no, id } = this.app.fields;
		const serv = this.app.service('OrderService');

		const where = {};
		if (out_trade_no) where['out_trade_no'] = out_trade_no;
		if (id) where['id'] = id;

		const data = await serv.info(where);

		return this.app.json({
			err_code: 0,
			data
		})
	}

	async save() {
		const params = this.app.fields;
		const { id } = params;
		const serv = this.app.service('OrderService');
		serv.save(params);

		return this.app.json({
			err_code: 0
		});
	}

	async delete() {
		const { id } = this.app.fields;
		const serv = this.app.service('OrderService');
		await serv.delete(id);

		return this.app.json({
			err_code: 0
		});
	}

	async confirm() {
		const serv = this.app.service('OrderService');
		const params = this.app.fields;

		params.user_id = this.app.auth?.id || 0;
		if (!params.out_trade_no) params.out_trade_no = `${dayjs().format('YYYYMMDDHHmmss')}${rand(1000, 9999)}`;

		//默认购买数量1
		if (!params.quantity) params.quantity = 1;

		//优惠金额
		if (params.is_coupon) {
			params.coupon_amount = params.coupon.amount || 0;
		}

		if (params.is_draft === 1) {
			params.draft_user_id = params.user_id;
			params.user_id = '';
		}

		//提交订单（如果订单编号已存在，则更新订单信息）
		const { id } = await serv.info({ out_trade_no: params.out_trade_no }) || {};
		if (id) params.id = id;

		await serv.save(params);

		//加入购物车
		if (params.is_cart === 1) {
			return this.app.json({
				err_code: 0
			})
		}
		//代客下单
		else if (params.is_draft === 1) {
			const weapp = this.app.make(Weapp);
			const { url_link: url } = await weapp.urlscheme('/pages/order/pay', `out_trade_no=${params.out_trade_no}`);

			return this.app.json({
				err_code: 0,
				data: {
					url
				}
			});
		}

		//获取订单信息
		const { pay_status, car_id, deposit, quantity, coupon_amount } = await serv.info({ out_trade_no: params.out_trade_no }) || {};

		//判断订单是否支付
		if (pay_status === 1) {
			return this.app.json({
				err_code: 0
			})
		}
		if (!params.car_id) params.car_id = car_id;

		const { weapp: { app_id: appid }, wxpay: { mch_id: mchid, key, public_key: publicKey, private_key: privateKey } } = this.app.config;
		//返回支付参数
		const wxpay = new WxPay({
			appid,
			mchid,
			publicKey,
			privateKey,
		});

		const { open_id } = await this.app.service('UserService').info({
			id: this.app.auth.id
		});

		const { name, version } = await this.app.service('CarService').info({
			id: params.car_id
		});

		//预付款=订金*数量-优惠额
		const amount = deposit * quantity - parseFloat(coupon_amount || 0);
		const { data: payment_params } = await wxpay.transactions_jsapi({
			description: `${name}${version}购车定金`,
			out_trade_no: params.out_trade_no,
			//必须先设置apiv3key才能回传
			notify_url: 'https://mp.kachewo.com/api/wxpay/callback/notify',
			amount: {
				total: Math.ceil(Number(amount) * 100),
				currency: "CNY"
			},
			payer: {
				openid: open_id,
			},
			scene_info: {
				payer_client_ip: '',
			},
		});

		//分发推荐奖|佣金|分红
		await this.app.service('JournalService').dispatch(params.out_trade_no);

		this.app.json({
			err_code: 0,
			data: {
				payment_params
			}
		})
	}

	//购物车合并支付
	async unipay() {
		const { id } = this.app.fields;

		const pay_union_id = `${dayjs().format('YYYYMMDDHHmmss')}${rand(1000, 9999)}`;
		await Order.update({
			pay_union_id
		}, {
			where: {
				id: { [sequelize.Op.in]: String(id).split(',') }
			}
		});

		const { open_id } = await this.app.service('UserService').info({
			id: this.app.auth.id
		});

		const { weapp: { app_id: appid }, wxpay: { mch_id: mchid, key, public_key: publicKey, private_key: privateKey } } = this.app.config;
		//返回支付参数
		const wxpay = new WxPay({
			appid,
			mchid,
			publicKey,
			privateKey,
		});
		//车辆信息
		const { data: info } = await this.app.service('OrderService').get({ id, is_cart: 1 });

		const totalAmount = info.map((d) => d.deposit * d.quantity - d.coupon_amount).reduce((total, current) => {
			return total + parseFloat(current);
		}, 0);

		const { data: payment_params } = await wxpay.transactions_jsapi({
			description: `${info.map(({ car: { name, version } }) => `${name}${version}`).splice(0, 2).join(',')}购车定金`,
			out_trade_no: pay_union_id,
			//必须先设置apiv3key才能回传
			notify_url: 'https://mp.kachewo.com/api/wxpay/callback/notify',
			amount: {
				total: Math.ceil(Number(totalAmount) * 100),
				currency: "CNY"
			},
			payer: {
				openid: open_id,
			},
			scene_info: {
				payer_client_ip: '',
			},
		});

		for (const order of info) {
			await this.app.service('JournalService').dispatch(order.out_trade_no);
		}

		this.app.json({
			err_code: 0,
			data: {
				payment_params
			}
		})
	}

	async wxpayNotify() {
		/*
		fs.writeFileSync('notify.txt', JSON.stringify(this.app.fields));

		const raw = '{"id":"890202dd-4ff8-5dcc-88f5-d917f8358a42","create_time":"2024-03-22T14:53:41+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"ReVLxZErIxUtmYNQbuMD4iZqC7zwnhx4LJw5O24z/5MdyQq9Y9PoMwM6F4N/u4ptvRkMPBiD+Zv5m3yXVXPHCy0REpkc9QUy5mVRxwGKXvLeho3Sw/4YfBtp40VusRwp2M8Q3BL57joQZ0i1UUoqi/1rr3ISD90ZtGZMYRCTiVTnkuWLXx/9m5L7a3ELV3aPIXxbFDLGCa90s4IYq9rU0BV/fXvXwou//fkdXzzX0kgkrATovjgmUC54gmN0i2QkY5BukJghHtm6yGIRK2CSsI2lHyyRujrLIfeXm848LGGSqJxD3DI9CFVji3YwZRLRfhNiT5gdfo5IQCcadjOxcREXfJncsSTaVkssSCPmsHgW4B1BaDZTbKZ9g4r9ruZgoBf6wW39pUhRg2wYNC1Ob4NcKoShdX09nt00nJ8LYtGqhDqj+oVyIR1k09n+RRc/OuZgWzNaULu+bUP7KmOddFBtqE9mnD24YymEREOXCYXdN4ymcPm2NdzaCfk075D2IyT7aS2fFv0vifu+8icaY5AYVBXA35cUxXSkY3lES5DOVNWkYttkFC+Eyh+1aS5sMg==","associated_data":"transaction","nonce":"DWMfURChMCUS"}}';
		const data = JSON.parse(raw);
		*/

		//验证签名
		const data = this.app.fields;

		const { weapp: { app_id: appid }, wxpay: { mch_id: mchid, key, public_key: publicKey, private_key: privateKey } } = this.app.config;
		const {
			ciphertext,
			associated_data,
			nonce
		} = data?.resource || {};

		//返回支付参数
		const wxpay = new WxPay({
			appid,
			mchid,
			publicKey,
			privateKey,
		});
		const {
			out_trade_no,
			transaction_id,
			trade_state,
			amount
		} = wxpay.decipher_gcm(ciphertext, associated_data, nonce, key);
		if (trade_state === 'SUCCESS') {
			const serv = this.app.service('OrderService');

			//判断是否为联合支付
			const { pay_union_id } = await serv.info({ pay_union_id: out_trade_no }) || {};
			if (pay_union_id) {
				Order.update({
					pay_status: 1,
					pay_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
					pay_amount: sequelize.literal(`deposit * quantity - coupon_amount`),
					is_draft: 0,
					is_cart: 0,
				}, {
					where: {
						pay_union_id
					}
				})
			}
			else {
				const { id } = await serv.info({ out_trade_no });
				await serv.save({
					id,
					pay_status: 1,
					pay_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
					pay_amount: parseFloat(amount.total / 100),
					//去掉代客下单标识
					is_draft: 0,
					//去掉购物车标识
					is_cart: 0,
				});
			}
		}

		this.app.xml('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
	}

	async wxpayRefundNotify() {
		/*
		fs.writeFileSync('notify.txt', JSON.stringify(this.app.fields));
		const raw = '{"id":"df89a7e5-b774-5c58-b81c-da060c9ec541","create_time":"2024-03-22T18:13:41+08:00","resource_type":"encrypt-resource","event_type":"REFUND.SUCCESS","summary":"退款成功","resource":{"original_type":"refund","algorithm":"AEAD_AES_256_GCM","ciphertext":"2o19h5q0gOL/TsGP3/b8ujubkKEfgjACMs1K0bTW8T5KFus17RNvjnRaCIRXoAfn+PQbOodtqfkSrCGQBxqNoKBIbjPcIhLRPb/Yllpd2YSFf4gtEBL2NdXW5KNJv4IVs4ntUyhuMBIIYNnfXwW+1HB9J4oHLX4+sriQ3hFnXBnXtQOYa0VmeAqBUiKO4Htiui8fBjDY7c/ujTEZstbucNzWANoT7Y2dCAJtg5NxNifnxFWXkzZ/BgziavBDqtrJI0/OiHBF6dGZ9rmAcdfNKKpkOYWEfkno/JXKbdpYonHW1bfReKm8JvXD8D/KMD06LP7mhQ3Srws3GJ4Ajuney3YXn0pe7rgJFZjyx/pNeScesSEWkqCotyMhmRikkynMjWdqkLo3OdI6v0EEvip3Itk564f1U7CcnpitCpCKaBXCtVYp9RZAmXiQvpxVbrnOYnEtSTLTQgzoMObZwd73bN1wL9RpS76MesqgPRT+h55dGR9enLr/kwUDBU9/fQ==","associated_data":"refund","nonce":"sNrXfNApdPe0"}}';
		const data = JSON.parse(raw);
		*/

		const data = this.app.fields;

		const { weapp: { app_id: appid }, wxpay: { mch_id: mchid, key, public_key: publicKey, private_key: privateKey } } = this.app.config;
		const {
			ciphertext,
			associated_data,
			nonce
		} = data?.resource || {};

		//返回支付参数
		const wxpay = new WxPay({
			appid,
			mchid,
			publicKey,
			privateKey,
		});

		// 解密回调信息
		const {
			refund_status,
			out_trade_no,
			out_refund_no,
			amount
		} = wxpay.decipher_gcm(ciphertext, associated_data, nonce, key);
		if (refund_status === 'SUCCESS') {
			const serv = this.app.service('OrderService');
			const { id } = await serv.info({ out_trade_no });

			await serv.save({
				id,
				pay_status: 0,
				pay_time: null,
				pay_amount: 0,

				//退款
				/*
				refund_status: 1,
				refund_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
				out_refund_no,
				refund_amount: parseFloat(amount.total / 100)
				*/
			});
		}

		this.app.xml('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
	}
}

exports = module.exports = OrderController;
